#include <ESP8266WiFi.h>
#include <PubSubClient.h>  // 需要去社区下载安装
#include <WiFiClient.h>
#include <Wire.h>
 
// 设置wifi接入信息(请根据您的WiFi信息进行修改)
const char* ssid = ""; 
const char* password = "";  
// mqtt配置
const char* mqttServer = ""; //局域网下的ipv4,可以通过cmd的ipconfig查看
const char* mqttUserName = "user";
const char* mqttPassword = "123456";
const char* TOPIC = "test/mqtt";


// 发布的消息
String msg = "";  

// ADXL345 I2C address is 0x53(83)
#define Addr 0x53

const uint8_t scl = D1; //D5
const uint8_t sda = D2; //D6
   
float xAccl, yAccl, zAccl;
 
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
 
void setup() {
  Serial.begin(9600);
   // 初始化I2C通信作为主机
    Wire.begin(sda, scl);
  //设置ESP8266工作模式为无线终端模式
  WiFi.mode(WIFI_STA);
 
  // 连接WiFi
  connectWifi();
 
  // 设置MQTT服务器和端口号
  mqttClient.setServer(mqttServer, 1883);
  // 连接MQTT服务器
  connectMQTTServer();
}
 
void loop() {
  
  if (mqttClient.connected()) { // 如果开发板成功连接服务器   
     handleroot(); 
     mqttClient.loop(); // 保持客户端心跳
  } else {                  // 如果开发板未能成功连接服务器
    connectMQTTServer();    // 则尝试连接服务器
  }
}
 
void connectMQTTServer(){
  // 根据ESP8266的MAC地址生成客户端ID（避免与其它ESP8266的客户端ID重名）
  String clientId = "esp8266-" + WiFi.macAddress();
 
  // 连接MQTT服务器
  if (mqttClient.connect(clientId.c_str(),mqttUserName,mqttPassword)) {
    Serial.println("MQTT Server Connected.");
    Serial.println("Server Address: ");
    Serial.println(mqttServer);
    Serial.println("ClientId:");
    Serial.println(clientId);
    mqttClient.subscribe(TOPIC);
  } else {
    Serial.print("MQTT Server Connect Failed. Client State:");
    Serial.println(mqttClient.state());
    delay(3000);
  }  
}
 
// ESP8266连接wifi
void connectWifi(){
 
  WiFi.begin(ssid, password);
 
  //等待WiFi连接,成功连接后输出成功信息
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");  
  Serial.println("");
}
// IIC 采集数据
void handleroot()
{
    unsigned int data[6];
    // 启动I2C传输
    Wire.beginTransmission(Addr);
    // 选择带宽速率寄存器
    Wire.write(0x2C);
    // Normal mode, Output data rate = 100 Hz
    Wire.write(0x0A);
    // 停止I2C传输
    Wire.endTransmission();

    // 启动I2C传输
    Wire.beginTransmission(Addr);
    // 选择功率控制寄存器
    Wire.write(0x2D);
    // Auto-sleep disable
    Wire.write(0x08);
    // 停止I2C传输
    Wire.endTransmission();

    // 启动I2C传输
    Wire.beginTransmission(Addr);
    // 选择数据格式寄存器
    Wire.write(0x31);
    // Self test disabled, 4-wire interface, Full resolution, Range = +/-2g
    Wire.write(0x08);
    // 停止I2C传输
    Wire.endTransmission();

    delay(300);
    for (int i = 0; i < 6; i++)
    {
    // 启动I2C传输
    Wire.beginTransmission(Addr);
    // 选择数据寄存器
    Wire.write((50 + i));
    // //停止I2C传输
    Wire.endTransmission();
    // 读取1字节数据
    Wire.requestFrom(Addr, 1);
    // 读取6字节数据
    // xAccl lsb, xAccl msb, yAccl lsb, yAccl msb, zAccl lsb, zAccl msb
    if (Wire.available() == 1)
    {
    data[i] = Wire.read();
    }
    }
    // 将数据转换为10位
    int xAccl = (((data[1] & 0x03) * 256) + data[0]);
    if (xAccl > 511)
        {
        xAccl -= 1024;
        }
    int yAccl = (((data[3] & 0x03) * 256) + data[2]);
    if (yAccl > 511)
        {
        yAccl -= 1024;
        }
    int zAccl = (((data[5] & 0x03) * 256) + data[4]);
    if (zAccl > 511)
        {
        zAccl -= 1024;
        }
    msg = "x#" + String(xAccl) + "#y#" + String(yAccl) +"#z#" + String(zAccl);
    mqttClient.publish(TOPIC, msg.c_str());
    msg = "";
    delay(500);
}
